package com.w.picture.manager;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.model.*;
import com.qcloud.cos.model.ciModel.persistence.PicOperations;
import com.w.picture.config.cos.CosProperties;
import com.w.picture.exception.BusinessException;
import com.w.picture.exception.ErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Title: CosManager
 * @Author wzp
 * @Date 2024/12/30 17:42
 * @description: 腾讯云对象存储管理
 */
@Slf4j
@Component
public class CosManager {

    @Resource
    private CosProperties cosProperties;
    @Resource
    private COSClient cosClient;

    // 上传图片时实时压缩:https://cloud.tencent.com/document/product/460/72229
    // 上传时处理接口信息:https://cloud.tencent.com/document/product/436/115609#.E4.B8.8A.E4.BC.A0.E6.97.B6.E5.A4.84.E7.90.86
    public PutObjectResult putPictureObject(String filePath, File file) {
        PicOperations picOperations = new PicOperations();
        picOperations.setIsPicInfo(1);//1返回原图信息
        List<PicOperations.Rule> rules = new ArrayList<>();
        // 图片压缩（转成 webp 格式）
        String webpKey = FileUtil.mainName(filePath) + ".webp";
        PicOperations.Rule compressRule = new PicOperations.Rule();
        compressRule.setRule("imageMogr2/format/webp");
        compressRule.setBucket(cosProperties.getBucket());
        compressRule.setFileId(webpKey);
        rules.add(compressRule);

        // 缩略图处理，仅对 > 20 KB 的图片生成缩略图
        if (file.length() > 2 * 1024) {
            PicOperations.Rule thumbnailRule = new PicOperations.Rule();
            thumbnailRule.setBucket(cosProperties.getBucket());
            String thumbnailKey = FileUtil.mainName(filePath) + "_thumbnail." + FileUtil.getSuffix(filePath);
            thumbnailRule.setFileId(thumbnailKey);
            // 缩放规则 /thumbnail/<Width>x<Height>>（如果大于原图宽高，则不处理）
            thumbnailRule.setRule(String.format("imageMogr2/thumbnail/%sx%s>", 128, 128));
            rules.add(thumbnailRule);
        }


        // 构造处理参数
        picOperations.setRules(rules);
        return putPictureObject(filePath, file, picOperations);
    }


    public PutObjectResult putPictureObject(String filePath, File file, PicOperations picOperations) {
        return putObject(filePath, file, picOperations);
    }

    /**
     * 上传文件
     *
     * @param filePath
     * @param file
     * @param picOperations 用于记录图像操作
     *                      isPicInfo 是否返回原图信息，0不返回原图信息，1返回原图信息，默认为0 int
     *                      rules 处理规则，一条规则对应一个处理结果（目前支持五条规则），不填则不进行图片处理 List
     *                      图片处理规则:https://cloud.tencent.com/document/product/436/55377
     *                      注意：使用图片处理记得开通数据万象：https://console.cloud.tencent.com/ci
     * @return
     */
    public PutObjectResult putObject(String filePath, File file, PicOperations picOperations) {
        log.info("cos 上传文件, filePath = {}", filePath);
        PutObjectRequest putObjectRequest = new PutObjectRequest(cosProperties.getBucket(), filePath, file);
        if (picOperations != null) {
            putObjectRequest.setPicOperations(picOperations);
        }
        PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
        log.info("cos 上传文件, result = {}", JSONUtil.toJsonStr(putObjectResult));
        return putObjectResult;
    }

    /**
     * 删除对象
     *
     * @param deleteKeys 文件 keys
     */
    public void deleteObject(List<String> deleteKeys) throws CosClientException {
        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(cosProperties.getBucket());
        // 设置要删除的key列表, 最多一次删除1000个
        ArrayList<DeleteObjectsRequest.KeyVersion> keyList = new ArrayList<>();
        // 传入要删除的文件名
        // 注意文件名不允许以正斜线/或者反斜线\开头，例如：
        // 存储桶目录下有a/b/c.txt文件，如果要删除，只能是 keyList.add(new KeyVersion("a/b/c.txt")),
        // 若使用 keyList.add(new KeyVersion("/a/b/c.txt"))会导致删除不成功
        for (String deleteKey : deleteKeys) {
            keyList.add(new DeleteObjectsRequest.KeyVersion(deleteKey));
        }
        deleteObjectsRequest.setKeys(keyList);
        cosClient.deleteObjects(deleteObjectsRequest);
    }

    /**
     * 获取图片主色调
     *
     * @param key 文件 key
     * @return 图片主色调
     * https://cloud.tencent.com/document/product/436/113310#.E5.8A.9F.E8.83.BD.E6.A6.82.E8.BF.B0
     */
    public String getImageAve(String key) {
        GetObjectRequest getObj = new GetObjectRequest(cosProperties.getBucket(), key);
        String rule = "imageAve";
        getObj.putCustomQueryParameter(rule, null);
        COSObject object = cosClient.getObject(getObj);
        COSObjectInputStream objectContent = object.getObjectContent();
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            CloseableHttpResponse httpResponse = httpClient.execute(objectContent.getHttpRequest());
            String response = EntityUtils.toString(httpResponse.getEntity());
            return JSONUtil.parseObj(response).getStr("RGB");
        } catch (IOException e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR.getCode(),e.getMessage());
        }
    }


}
